/**
 *    @file       clienttask.cpp
 *
 *    @brief      
 *    @details
 *
 *    @version    1.0
 *    @date       02/21/2014 11:23:50 AM
 *
 *    @author     Theophilus (), wangtf418@gmail.com
 */
#include "clienttask.h"
#include "server.h"
#include "netprocessthread.h"

clienttask::clienttask(csocket *sock, netprocessthread *netthread, const comargs *args /* = NULL */)
	: servertask(sock, netthread, args), m_connect_flag(false)
{

}

clienttask::~clienttask()
{

}

bf_int_t clienttask::init(bf_time_t timeout /*  = SOCKTASK_TIMEOUT */, bf_int_t sock_buflen /*  = 102400 */)
{
	if (!m_args)
	{
		return BF_ERROR;
	}

	if (!m_socket)
	{
		m_socket = new csocket;
	}

	bf_int_t ret = m_socket->socket(SOCK_STREAM);
	if (ret != BF_OK)
	{
		return BF_ERROR;
	}

	reset_buf();
	m_timeout = timeout;

	m_socket->set_nonblock_opt(false);
	m_socket->set_tcpnodelay_opt(true);

	m_socket->set_recvbuf_opt(sock_buflen);
	m_socket->set_sendbuf_opt(sock_buflen);

	client_addr_args *args = (client_addr_args*)m_args;
	m_socket->connect(args->m_srvip, args->m_srvport);

	add_to_epoll((BF_EPOLL_IN | BF_EPOLL_OUT));
	return BF_OK;
}

bf_int_t clienttask::process_io_event(bf_int_t events)
{
	if ((events & BF_EPOLL_ERR) || (events & BF_EPOLL_HUP))
	{
		destroy();
		return BF_ERROR;
	}

	m_last_activetime = server::get()->get_time();

	bf_int_t ret = BF_OK;
	if (events & BF_EPOLL_IN)
	{
		ret = recv_process();
		if (ret == BF_ERROR)
		{
			destroy();
			return BF_ERROR;
		}
	}

	if (events & BF_EPOLL_OUT)
	{
		if (m_connect_flag)
		{
			ret = send_process();
			if (ret == BF_ERROR)
			{
				destroy();
				return BF_ERROR;
			}
		}
		else
		{
			if (m_socket->get_socket_error() != 0)
			{
				destroy();
				return BF_ERROR;
			}
			m_connect_flag = true;

			ret = send_process();
			if (ret == BF_ERROR)
			{
				destroy();
				return BF_ERROR;
			}
		}
	}

	if (m_close_flag && ret == BF_SUCC)
	{
		destroy();
	}

	return BF_OK;
}

bf_int_t clienttask::process_recv_packet(bf_char_t *buf, bf_size_t buflen)
{
	client_addr_args *args = (client_addr_args*)m_args;

	bf_char_t *newbuf = new bf_char_t[buflen];
	memcpy(newbuf, buf, buflen);
	clientres_bufmsgbody *body = new clientres_bufmsgbody(newbuf, buflen, BF_OK, args->m_sequence_num);

	m_netthread->send_msg(args->m_thd_type, args->m_thd_index, args->m_tsk_id, MSG_TYPE_RECVRES, body, m_taskid);
	return BF_OK;
}

